package com.gqz.patrol.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.gqz.common.core.domain.RequestForm;
import com.gqz.common.core.utils.poi.ExcelUtil;
import com.gqz.common.core.utils.query.QueryMapperUtil;
import com.gqz.patrol.app.entity.EnPatrolTaskEntity;
import com.gqz.patrol.app.entity.EnPatrolTaskEquipEntity;
import com.gqz.patrol.app.entity.EnPatrolTaskOperateEntity;
import com.gqz.patrol.app.entity.EnWzJfEquipEntity;
import com.gqz.patrol.app.mapper.EnPatrolTaskEquipMapper;
import com.gqz.patrol.app.mapper.EnPatrolTaskMapper;
import com.gqz.patrol.app.mapper.EnPatrolTaskOperateMapper;
import com.gqz.patrol.app.mapstruct.EnPatrolTaskEquipMapstruct;
import com.gqz.patrol.app.mapstruct.EnPatrolTaskMapstruct;
import com.gqz.patrol.entity.EnStockEquipDefectEntity;
import com.gqz.patrol.mapper.EnStockEquipDefectMapper;
import com.gqz.patrol.mapstruct.EnStockEquipDefectMapstruct;
import com.gqz.patrol.service.IEnPatrolTaskService;
import com.gqz.patrol.vo.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 能源-巡视工单表 ҵ���߼�ʵ�ֲ�ServiceImpl
 */
@Service
@Slf4j
public class EnPatrolTaskServiceImpl extends ServiceImpl<EnPatrolTaskMapper, EnPatrolTaskEntity> implements IEnPatrolTaskService {

    @Resource
    private EnPatrolTaskMapstruct mapstruct;

    @Resource
    private EnPatrolTaskEquipMapstruct equipMapstruct;

    @Resource
    private EnPatrolTaskEquipMapper taskEquipMapper;

    @Resource
    private EnStockEquipDefectMapstruct equipDefectMapstruct;

    @Resource
    private EnStockEquipDefectMapper equipDefectMapper;

    @Resource
    private EnPatrolTaskOperateMapper taskOperateMapper;

    @Override
    public List<EnPatrolTaskVo> getById(String id) {
        MPJLambdaWrapper<EnPatrolTaskEntity> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.eq(EnPatrolTaskEntity::getId, id);
        queryWrapper.selectAll(EnPatrolTaskEntity.class);
        List<EnPatrolTaskEntity> entities = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(entities)) {
            return mapstruct.toVos(entities);
        }
        return new ArrayList<>();
    }

    @Override
    public List<EnPatrolTaskVo> getByTaskNo(String TaskNo) {
        MPJLambdaWrapper<EnPatrolTaskEntity> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.eq(EnPatrolTaskEntity::getTaskNo, TaskNo);
        queryWrapper.selectAll(EnPatrolTaskEntity.class);
        List<EnPatrolTaskEntity> entities = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(entities)) {
            return mapstruct.toVos(entities);
        }
        return new ArrayList<>();
    }

    @Override
    public Page<EnPatrolTaskVo> page(RequestForm<EnPatrolTaskVo> requestForm) {
        EnPatrolTaskEntity entity = mapstruct.toEntity(requestForm.getEntity());
        MPJLambdaWrapper<EnPatrolTaskEntity> queryWrapper = QueryMapperUtil.initQueryWrapper(entity, requestForm);
        queryWrapper.clear();
        queryWrapper.selectAll(EnPatrolTaskEntity.class);
        if (entity.getPlanStartTime() != null && !"".equals(entity.getPlanStartTime())) {
            queryWrapper.ge(EnPatrolTaskEntity::getPlanStartTime, entity.getPlanStartTime());
        }
        if (entity.getPlanEndTime() != null && !"".equals(entity.getPlanEndTime())) {
            queryWrapper.le(EnPatrolTaskEntity::getPlanStartTime, entity.getPlanEndTime());
        }
        queryWrapper.like(StringUtils.isNotBlank(entity.getTaskName()), EnPatrolTaskEntity::getTaskName, entity.getTaskName());
        queryWrapper.like(StringUtils.isNotBlank(entity.getPatrolRoomName()), EnPatrolTaskEntity::getPatrolRoomName, entity.getPatrolRoomName());
        queryWrapper.eq(StringUtils.isNotBlank(entity.getMaintainUnitNo()), EnPatrolTaskEntity::getMaintainUnitNo, entity.getMaintainUnitNo());
        queryWrapper.eq(StringUtils.isNotBlank(entity.getPatrolTypeNo()), EnPatrolTaskEntity::getPatrolTypeNo, entity.getPatrolTypeNo());
        queryWrapper.eq(StringUtils.isNotBlank(entity.getPTaskStatusNo()), EnPatrolTaskEntity::getPTaskStatusNo, entity.getPTaskStatusNo());
        queryWrapper.eq(EnPatrolTaskEntity::getIsDel, "0");


        queryWrapper.orderByDesc(EnPatrolTaskEntity::getPlanStartTime);
        Page<EnPatrolTaskEntity> page = Page.of(requestForm.getPageNo(), requestForm.getPageSize());
        //page = baseMapper.selectPage(page, queryWrapper);
        IPage<EnPatrolTaskEntity> iPage = baseMapper.selectJoinPage(page, EnPatrolTaskEntity.class, queryWrapper);
        page.setRecords(iPage.getRecords());
        page.setTotal(iPage.getTotal());
        return mapstruct.toVos(page);
    }

    @Override
    public Long count(RequestForm<EnPatrolTaskVo> requestForm) {
        EnPatrolTaskEntity entity = mapstruct.toEntity(requestForm.getEntity());
        MPJLambdaWrapper<EnPatrolTaskEntity> queryWrapper = QueryMapperUtil.initQueryWrapper(entity, requestForm);

        queryWrapper.select(EnPatrolTaskEntity::getId);
        return baseMapper.selectCount(queryWrapper);
    }

    @Override
    public int insert(List<EnPatrolTaskVo> forms) {
        List<EnPatrolTaskEntity> entitys = mapstruct.toEntitys(forms);
        int result = 0;
        for (int i = 0, size = entitys.size(); i < size; i++) {
            EnPatrolTaskEntity entity = entitys.get(i);
            result += baseMapper.insert(entity);
        }
        return result;
    }

    @Override
    public int update(List<EnPatrolTaskVo> forms) {
        List<EnPatrolTaskEntity> entitys = mapstruct.toEntitys(forms);
        int result = 0;
        for (EnPatrolTaskEntity entity : entitys) {
            if ("99".equals(entity.getPTaskStatusNo()) && "1".equals(entity.getAppraiseStatus())) {
                // 归档操作并且合格，插入操作记录
                this.saveTaskOperate(mapstruct.toVo(entity), "99", "归档");
            } else if ("99".equals(entity.getPTaskStatusNo()) && "2".equals(entity.getAppraiseStatus())) {
                // 归档操作但不合格，回退到接单环节
                this.saveTaskOperate(mapstruct.toVo(entity), "15", "质量评价不合格");
                entity.setPTaskStatusNo("15");
                entity.setPTaskStatusName("已接单");
                entity.setATaskStatusName("退单");
                entity.setATaskStatusNo("3");
            }
            result += baseMapper.updateById(entity);
        }
        return result;
    }

    @Override
    public List<EnPatrolTaskEquipVo> getTaskEquipList(String taskNo) {
        MPJLambdaWrapper<EnPatrolTaskEquipEntity> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper
                .selectAll(EnPatrolTaskEquipEntity.class)
                .select(EnWzJfEquipEntity::getGldwbm)
                .select(EnWzJfEquipEntity::getGldwmc)
                .select(EnWzJfEquipEntity::getCcbm)
                .select(EnWzJfEquipEntity::getZb)
                .innerJoin(EnWzJfEquipEntity.class, EnWzJfEquipEntity::getSbbm, EnPatrolTaskEquipEntity::getEquipNo)
                .eq(EnPatrolTaskEquipEntity::getTaskNo, taskNo)
                .eq(EnPatrolTaskEquipEntity::getIsDel, "0")
                .eq(EnWzJfEquipEntity::getSfsc, "0");
        List<EnPatrolTaskEquipEntity> patrolEquipEntities = taskEquipMapper.selectList(queryWrapper);

        return patrolEquipEntities.stream().map(item -> equipMapstruct.toVo(item)).collect(Collectors.toList());
    }

    @Override
    public List<EnStockEquipDefectVo> getTaskDefectList(String taskNo) {
        MPJLambdaWrapper<EnStockEquipDefectEntity> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(EnStockEquipDefectEntity.class);
        queryWrapper.eq(EnStockEquipDefectEntity::getTaskNo, taskNo);
        List<EnStockEquipDefectEntity> stockEquipEntities = equipDefectMapper.selectList(queryWrapper);

        return stockEquipEntities.stream().map(item -> equipDefectMapstruct.toVo(item)).collect(Collectors.toList());
    }

    @Override
    public EnPatrolTaskProcessVo getTaskProcess(String taskNo) {
        EnPatrolTaskProcessVo returnVo = new EnPatrolTaskProcessVo();
        List<EnTaskOperateVo> taskOperateVos = getBaseProcessList(taskNo);

        LambdaQueryWrapper<EnPatrolTaskOperateEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EnPatrolTaskOperateEntity::getTaskNo, taskNo);
        queryWrapper.orderByAsc(EnPatrolTaskOperateEntity::getOptStatus);
        List<EnPatrolTaskOperateEntity> taskOperateEntities = taskOperateMapper.selectList(queryWrapper);
        String optStatus = setProcessDateAndGetNodeStatus(taskOperateEntities, taskOperateVos);

        this.setNodeAndFormatDate(optStatus, taskOperateVos, returnVo);

        return returnVo;
    }

    /**
     * 获取基础流程list
     *
     * @param taskNo
     * @return
     */

    private List<EnTaskOperateVo> getBaseProcessList(String taskNo) {
        LambdaQueryWrapper<EnPatrolTaskEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EnPatrolTaskEntity::getTaskNo, taskNo);
        EnPatrolTaskEntity taskEntity = baseMapper.selectOne(queryWrapper);

        List<EnTaskOperateVo> processVos = new ArrayList<>();
        processVos.add(new EnTaskOperateVo("工单编制", formatDate(taskEntity.getCreatTime(), "yyyy-MM-dd HH:mm:ss"), 0, 1, "0", "1"));
        processVos.add(new EnTaskOperateVo("派单", "", 0, 0, "10", "2"));
        processVos.add(new EnTaskOperateVo("接单", "", 0, 0, "15", "3"));
        processVos.add(new EnTaskOperateVo("到达现场", "", 0, 0, "20", "4"));
        processVos.add(new EnTaskOperateVo("巡视结束", "", 0, 0, "30", "5"));
        processVos.add(new EnTaskOperateVo("归档", "", 0, 0, "99", "7"));
        return processVos;
    }

    public String formatDate(Date date, String dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        if (date == null) {
            return "";
        }
        return sdf.format(date);
    }

    /**
     * 设置时间并且获取节点状态
     *
     * @param taskOperateEntities
     * @param taskOperateVos
     * @return
     */
    private String setProcessDateAndGetNodeStatus(List<EnPatrolTaskOperateEntity> taskOperateEntities, List<EnTaskOperateVo> taskOperateVos) {
        String optStatus = "0";
        for (EnTaskOperateVo process : taskOperateVos) {
            List<EnPatrolTaskOperateEntity> collect = taskOperateEntities.stream().filter(item -> process.getOptStatus().equals(item.getOptStatus())).collect(Collectors.toList());
            if (collect.isEmpty()) {
                continue;
            }
            optStatus = process.getOptStatus();
            process.setIsActive(1);
            process.setProcessDate(DateUtil.format(collect.get(0).getOptTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        return optStatus;
    }

    /**
     * 设置是否此节点和格式化时间
     *
     * @param optStatus
     * @param taskOperateVos
     * @param processVo
     */
    private void setNodeAndFormatDate(String optStatus, List<EnTaskOperateVo> taskOperateVos, EnPatrolTaskProcessVo processVo) {
        String year = taskOperateVos.get(0).getProcessDate().substring(0, 4);
        int activeSteps = 0;
        for (int i = 0; i < taskOperateVos.size(); i++) {
            EnTaskOperateVo process = taskOperateVos.get(i);
            //已归档不用闪烁
            if (optStatus.equals(process.getOptStatus())) {
                process.setIsNode(1);
                activeSteps = i + 1;
            }
            if (StringUtils.isBlank(process.getProcessDate())) {
                continue;
            }
            if (!"0".equals(process.getOptStatus()) && year.equals(process.getProcessDate().substring(0, 4))) {
                process.setProcessDate(process.getProcessDate().substring(5));
            } else {
                year = process.getProcessDate().substring(0, 4);
            }
        }
        processVo.setActiveSteps(activeSteps);
        processVo.setOperateVoList(taskOperateVos);
    }

    @Override
    public List<EnStockEquipDefectVo> getTaskHandleDefectList(String handleTaskNo) {
        MPJLambdaWrapper<EnStockEquipDefectEntity> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(EnStockEquipDefectEntity.class);
        queryWrapper.eq(EnStockEquipDefectEntity::getHandleTaskNo, handleTaskNo);
        List<EnStockEquipDefectEntity> stockEquipDefectEntities = equipDefectMapper.selectList(queryWrapper);

        return stockEquipDefectEntities.stream().map(item -> equipDefectMapstruct.toVo(item)).collect(Collectors.toList());
    }

    /**
     * 保存任务操作
     *
     * @param taskVo        taskVo
     * @param optStatus     optStatus
     * @param optStatusName optStatusName
     */
    @Override
    public void saveTaskOperate(EnPatrolTaskVo taskVo, String optStatus, String optStatusName) {
        EnPatrolTaskOperateEntity operateEntity = new EnPatrolTaskOperateEntity();
        operateEntity.setTaskNo(taskVo.getTaskNo());
        operateEntity.setOptStatus(optStatus);
        operateEntity.setOptStatusName(optStatusName);
        operateEntity.setOptTime(new Date());

        taskOperateMapper.insert(operateEntity);
    }

    /**
     * 将巡视任务导出成Excel
     *
     * @param resp
     * @param requestForm
     */
    @Override
    public void exportExcel(HttpServletResponse resp, RequestForm<EnPatrolTaskExcelVo> requestForm) {
        //设置信息头，告诉浏览器内容为excel类型
        resp.setHeader("content-Type", "application/vnd.ms-excel");
        //文件名称
        String fileName = "巡视工单信息.xls";
        //sheet名称
        String sheetName = "巡视工单表列表";
        fileName = new String(fileName.getBytes(), StandardCharsets.UTF_8);
        //设置下载名称
        resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        if (requestForm.getPageSize() < 1000L) {
            requestForm.setPageSize(1000L);
        }
        //获取到业务数据
        Page<EnPatrolTaskVo> page = this.page(mapstruct.toVo(requestForm));
        Page<EnPatrolTaskExcelVo> excelVoPage = mapstruct.toExcelVos(page);
        //导入excel
        new ExcelUtil<>(EnPatrolTaskExcelVo.class).exportExcel(resp, excelVoPage.getRecords(), sheetName);
    }

    @Override
    public List<EnTjVo> getGdStatusXx(String sdate, String edate) {
        MPJLambdaWrapper<EnPatrolTaskEntity> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.eq(EnPatrolTaskEntity::getIsDel, "0");
        queryWrapper.selectCount(EnPatrolTaskEntity::getTaskNo, "num");
        queryWrapper.selectAs(EnPatrolTaskEntity::getPTaskStatusNo, "statusCode");
        queryWrapper.selectAs(EnPatrolTaskEntity::getPTaskStatusName, "statusName");
        queryWrapper.groupBy(EnPatrolTaskEntity::getPTaskStatusNo, EnPatrolTaskEntity::getPTaskStatusName);
        try {
            Date startDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sdate);
            Date endDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(edate);
            if (startDateTime != null && !"".equals(startDateTime)) {
                queryWrapper.ge(EnPatrolTaskEntity::getPlanStartTime, startDateTime);
            }
            if (endDateTime != null && !"".equals(endDateTime)) {
                queryWrapper.le(EnPatrolTaskEntity::getPlanStartTime, endDateTime);
            }
            List<EnTjVo> entities = baseMapper.selectJoinList(EnTjVo.class, queryWrapper);
            return entities;
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }

}
